home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / • Other Platforms / PCCTS 1.31 / h / ATokenBuffer.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-10  |  5.9 KB  |  199 lines  |  [TEXT/MPS ]

  1. /* ANTLRTokenBuffer.C
  2.  *
  3.  * SOFTWARE RIGHTS
  4.  *
  5.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  6.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  7.  * company may do whatever they wish with source code distributed with
  8.  * PCCTS or the code generated by PCCTS, including the incorporation of
  9.  * PCCTS, or its output, into commerical software.
  10.  * 
  11.  * We encourage users to develop software with PCCTS.  However, we do ask
  12.  * that credit is given to us for developing PCCTS.  By "credit",
  13.  * we mean that if you incorporate our source code into one of your
  14.  * programs (commercial product, research project, or otherwise) that you
  15.  * acknowledge this fact somewhere in the documentation, research report,
  16.  * etc...  If you like PCCTS and have developed a nice tool with the
  17.  * output, please mention that you developed it using PCCTS.  In
  18.  * addition, we ask that this header remain intact in our source code.
  19.  * As long as these guidelines are kept, we expect to continue enhancing
  20.  * this system and expect to make other tools available as they are
  21.  * completed.
  22.  *
  23.  * ANTLR 1.31
  24.  * Terence Parr
  25.  * Parr Research Corporation
  26.  * with Purdue University and AHPCRC, University of Minnesota
  27.  * 1989-1995
  28.  */
  29.  
  30. typedef int TokenType;    // fool AToken.h into compiling
  31. #include "config.h"
  32. #include ATOKENBUFFER_H
  33.  
  34. ANTLRTokenBuffer::
  35. ANTLRTokenBuffer(ANTLRTokenStream *input, int k, int cs)
  36. {
  37.     this->input = input;
  38.     this->k = k;
  39.     buffer_size = chunk_size = cs;
  40. #ifdef OLD
  41.     buffer = (ANTLRAbstractToken **)calloc(chunk_size,
  42.                                              sizeof(ANTLRAbstractToken *));
  43. #else
  44.     buffer = ((ANTLRAbstractToken **)
  45.              calloc(chunk_size+1,sizeof(ANTLRAbstractToken *)))+1;
  46. #endif
  47.     if ( buffer == NULL ) {
  48.         panic("cannot alloc token buffer");
  49.     }
  50.     tp = &buffer[0];
  51.     last = tp-1;
  52.     next = &buffer[0];
  53.     num_markers = 0;
  54.     end_of_buffer = &buffer[buffer_size-1];
  55. }
  56.  
  57. ANTLRTokenBuffer::
  58. ~ANTLRTokenBuffer()
  59. {
  60.     if ( buffer!=NULL ) free((char *)(buffer-1));
  61. }
  62.  
  63. //#include <stdio.h>
  64.  
  65. ANTLRAbstractToken *ANTLRTokenBuffer::
  66. getToken()
  67. {
  68.     if ( tp <= last )            // is there any buffered lookahead still to be read?
  69.     {
  70.         return *tp++;            // read buffered lookahead
  71.     }
  72.     // out of buffered lookahead, get some more "real" input from getANTLRToken()
  73.     if ( next > end_of_buffer )    // buffer overflow?
  74.     {
  75. //        fprintf(stderr, "getToken: next > end_of_buffer (size is %d)\n", buffer_size);
  76.         makeRoom();
  77.     }
  78.     *next = getANTLRToken();
  79.     last = next;
  80.     next++;
  81.     tp = last;
  82.     return *tp++;
  83. }
  84.  
  85. void ANTLRTokenBuffer::
  86. rewind(int pos)
  87. {
  88.     tp = &buffer[pos];
  89.     num_markers--;
  90. }
  91.  
  92. /*
  93.  * This function is used to specify that the token pointers read
  94.  * by the ANTLRTokenBuffer should be buffered up (to be reused later).
  95.  */
  96. int ANTLRTokenBuffer::
  97. mark()
  98. {
  99.     num_markers++;
  100.     return tp - buffer;
  101. }
  102.  
  103. /*
  104.  * returns the token pointer n positions ahead.
  105.  * This implies that bufferedToken(1) gets the NEXT symbol of lookahead.
  106.  * This is used in conjunction with the ANTLRParser lookahead buffer.
  107.  *
  108.  * No markers are set or anything.  A bunch of input is buffered--that's all.
  109.  * The tp pointer is left alone as the lookahead has not been advanced
  110.  * with getToken().  The next call to getToken() will find a token
  111.  * in the buffer and won't have to call getANTLRToken().
  112.  *
  113.  * If this is called before a consume() is done, how_many_more_i_need is
  114.  * set to 'n'.
  115.  */
  116. ANTLRAbstractToken *ANTLRTokenBuffer::
  117. bufferedToken(int n)
  118. {
  119.     int how_many_more_i_need = (last-tp < 0) ? n : n-(last-tp)-1;
  120.     // Make sure that at least n tokens are available in the buffer
  121. //    fprintf(stderr, "bufferedToken(%d)\n", n);
  122.     for (int i=1; i<=how_many_more_i_need; i++)
  123.     {
  124.         if ( next > end_of_buffer )    // buffer overflow?
  125.         {
  126.             extendBuffer();
  127.         }
  128.         *next = getANTLRToken();
  129.         last = next;
  130.         next++;
  131.     }
  132.     return tp[n - 1];
  133. }
  134.  
  135. /* If no markers are set, the none of the input needs to be saved (except
  136.  * for the lookahead Token pointers).  We save only k-1 token pointers as
  137.  * we are guaranteed to do a getANTLRToken() right after this because otherwise
  138.  * we wouldn't have needed to extend the buffer.
  139.  *
  140.  * If there are markers in the buffer, we need to save things and so
  141.  * extendBuffer() is called.
  142.  */
  143. void ANTLRTokenBuffer::
  144. makeRoom()
  145. {
  146. //    fprintf(stderr, "in makeRoom.................\n");
  147.     if ( num_markers == 0 )
  148.     {
  149. //        fprintf(stderr, "num_markers==0; moving lookahead and resetting next\n");
  150. //        fprintf(stderr, "before: tp=%d, last=%d, next=%d\n", tp-buffer, last-buffer, next-buffer);
  151.         // reset the buffer to initial conditions, but move k-1 lookahead symbols
  152.         // to the beginning of buffer and put new input symbol at k
  153.         ANTLRAbstractToken **p = buffer, **q = end_of_buffer-(k-1);
  154. //        fprintf(stderr, "lookahead buffer = [");
  155.         for (int i=1; i<=k; i++)
  156.         {
  157.             *p++ = *q++;
  158. //            fprintf(stderr, " '%s'", ((ANTLRCommonToken *)buffer[i-1])->getText());
  159.         }
  160. //        fprintf(stderr, "]\n");
  161.         next = &buffer[k];
  162.         tp = &buffer[k];    // tp points to what will be filled in next
  163.         last = tp-1;
  164. //        fprintf(stderr, "after: tp=%d, last=%d, next=%d\n", tp-buffer, last-buffer, next-buffer);
  165.     }
  166.     else {
  167.         extendBuffer();
  168.     }
  169. }
  170.  
  171. /* This function extends 'buffer' by chunk_size and returns with all
  172.  * pointers at the same relative positions in the buffer (the buffer base
  173.  * address could have changed in realloc()) except that 'next' comes
  174.  * back set to where the next token should be stored.  All other pointers
  175.  * are untouched.
  176.  */
  177. void
  178. ANTLRTokenBuffer::
  179. extendBuffer()
  180. {
  181.     int save_last = last-buffer, save_tp = tp-buffer, save_next = next-buffer;
  182. //    fprintf(stderr, "extending physical buffer\n");
  183.     buffer_size += chunk_size;
  184. #ifdef OLD
  185.     buffer = (ANTLRAbstractToken **)
  186.              realloc((char *)buffer, buffer_size * sizeof(ANTLRAbstractToken *));
  187. #else
  188.     buffer = ((ANTLRAbstractToken **)
  189.              realloc((char *)(buffer-1), (buffer_size+1)*sizeof(ANTLRAbstractToken *)))+1;
  190. #endif
  191.     if ( buffer == NULL ) {
  192.         panic("cannot alloc token buffer");
  193.     }
  194.     tp = buffer + save_tp;    // put the pointers back to same relative position
  195.     last = buffer + save_last;
  196.     next = buffer + save_next;
  197.     end_of_buffer = &buffer[buffer_size-1];
  198. }
  199.